// 模型缓存管理工具
import { ref } from 'vue'

// 最大缓存数量
const MAX_MODEL_CACHE_SIZE = 10
// 最大贴图缓存数量
const MAX_TEXTURE_CACHE_SIZE = 50

// 创建LRU缓存
class LRUCache {
  constructor(maxSize = 10) {
    this.maxSize = maxSize
    this.cache = new Map()
  }

  get(key) {
    if (this.cache.has(key)) {
      // 移动到最后（最近使用）
      const value = this.cache.get(key)
      this.cache.delete(key)
      this.cache.set(key, value)
      return value
    }
    return null
  }

  set(key, value) {
    if (this.cache.has(key)) {
      this.cache.delete(key)
    } else if (this.cache.size >= this.maxSize) {
      // 删除最久未使用的项
      const firstKey = this.cache.keys().next().value
      this.deleteAndDispose(firstKey)
    }
    this.cache.set(key, value)
  }

  deleteAndDispose(key) {
    const item = this.cache.get(key)
    if (item) {
      // 如果是Three.js对象，释放资源
      if (item.dispose && typeof item.dispose === 'function') {
        try {
          item.dispose()
        } catch (e) {
          console.warn('Failed to dispose item:', e)
        }
      }
      // 如果是包含Three.js对象的模型，递归释放
      else if (item.traverse && typeof item.traverse === 'function') {
        try {
          item.traverse((child) => {
            // 释放几何体
            if (child.geometry) {
              try {
                child.geometry.dispose()
              } catch (e) {
                console.warn('Failed to dispose geometry:', e)
              }
            }
            
            // 释放材质
            if (child.material) {
              try {
                if (Array.isArray(child.material)) {
                  child.material.forEach(material => {
                    // 释放材质中的贴图
                    if (material.map) {
                      try {
                        material.map.dispose()
                      } catch (e) {
                        console.warn('Failed to dispose material map:', e)
                      }
                    }
                    if (material.lightMap) {
                      try {
                        material.lightMap.dispose()
                      } catch (e) {
                        console.warn('Failed to dispose light map:', e)
                      }
                    }
                    if (material.aoMap) {
                      try {
                        material.aoMap.dispose()
                      } catch (e) {
                        console.warn('Failed to dispose ao map:', e)
                      }
                    }
                    if (material.emissiveMap) {
                      try {
                        material.emissiveMap.dispose()
                      } catch (e) {
                        console.warn('Failed to dispose emissive map:', e)
                      }
                    }
                    if (material.bumpMap) {
                      try {
                        material.bumpMap.dispose()
                      } catch (e) {
                        console.warn('Failed to dispose bump map:', e)
                      }
                    }
                    if (material.normalMap) {
                      try {
                        material.normalMap.dispose()
                      } catch (e) {
                        console.warn('Failed to dispose normal map:', e)
                      }
                    }
                    if (material.displacementMap) {
                      try {
                        material.displacementMap.dispose()
                      } catch (e) {
                        console.warn('Failed to dispose displacement map:', e)
                      }
                    }
                    if (material.roughnessMap) {
                      try {
                        material.roughnessMap.dispose()
                      } catch (e) {
                        console.warn('Failed to dispose roughness map:', e)
                      }
                    }
                    if (material.metalnessMap) {
                      try {
                        material.metalnessMap.dispose()
                      } catch (e) {
                        console.warn('Failed to dispose metalness map:', e)
                      }
                    }
                    if (material.alphaMap) {
                      try {
                        material.alphaMap.dispose()
                      } catch (e) {
                        console.warn('Failed to dispose alpha map:', e)
                      }
                    }
                    if (material.envMap) {
                      try {
                        material.envMap.dispose()
                      } catch (e) {
                        console.warn('Failed to dispose env map:', e)
                      }
                    }
                    try {
                      material.dispose()
                    } catch (e) {
                      console.warn('Failed to dispose material:', e)
                    }
                  })
                } else {
                  // 释放材质中的贴图
                  if (child.material.map) {
                    try {
                      child.material.map.dispose()
                    } catch (e) {
                      console.warn('Failed to dispose material map:', e)
                    }
                  }
                  if (child.material.lightMap) {
                    try {
                      child.material.lightMap.dispose()
                    } catch (e) {
                      console.warn('Failed to dispose light map:', e)
                    }
                  }
                  if (child.material.aoMap) {
                    try {
                      child.material.aoMap.dispose()
                    } catch (e) {
                      console.warn('Failed to dispose ao map:', e)
                    }
                  }
                  if (child.material.emissiveMap) {
                    try {
                      child.material.emissiveMap.dispose()
                    } catch (e) {
                      console.warn('Failed to dispose emissive map:', e)
                    }
                  }
                  if (child.material.bumpMap) {
                    try {
                      child.material.bumpMap.dispose()
                    } catch (e) {
                      console.warn('Failed to dispose bump map:', e)
                    }
                  }
                  if (child.material.normalMap) {
                    try {
                      child.material.normalMap.dispose()
                    } catch (e) {
                      console.warn('Failed to dispose normal map:', e)
                    }
                  }
                  if (child.material.displacementMap) {
                    try {
                      child.material.displacementMap.dispose()
                    } catch (e) {
                      console.warn('Failed to dispose displacement map:', e)
                    }
                  }
                  if (child.material.roughnessMap) {
                    try {
                      child.material.roughnessMap.dispose()
                    } catch (e) {
                      console.warn('Failed to dispose roughness map:', e)
                    }
                  }
                  if (child.material.metalnessMap) {
                    try {
                      child.material.metalnessMap.dispose()
                    } catch (e) {
                      console.warn('Failed to dispose metalness map:', e)
                    }
                  }
                  if (child.material.alphaMap) {
                    try {
                      child.material.alphaMap.dispose()
                    } catch (e) {
                      console.warn('Failed to dispose alpha map:', e)
                    }
                  }
                  if (child.material.envMap) {
                    try {
                      child.material.envMap.dispose()
                    } catch (e) {
                      console.warn('Failed to dispose env map:', e)
                    }
                  }
                  try {
                    child.material.dispose()
                  } catch (e) {
                    console.warn('Failed to dispose material:', e)
                  }
                }
              } catch (e) {
                console.warn('Failed to dispose material:', e)
              }
            }
            
            // 释放纹理
            if (child.texture) {
              try {
                child.texture.dispose()
              } catch (e) {
                console.warn('Failed to dispose texture:', e)
              }
            }
          })
        } catch (e) {
          console.warn('Failed to traverse item:', e)
        }
      }
    }
    this.cache.delete(key)
  }

  clear() {
    // 清理所有资源
    for (const key of this.cache.keys()) {
      this.deleteAndDispose(key)
    }
    this.cache.clear()
  }

  size() {
    return this.cache.size
  }
}

// 创建模型缓存实例
export const modelCacheManager = new LRUCache(MAX_MODEL_CACHE_SIZE)
// 创建贴图缓存实例
export const textureCacheManager = new LRUCache(MAX_TEXTURE_CACHE_SIZE)

// 清理所有缓存
export const clearAllCaches = () => {
  modelCacheManager.clear()
  textureCacheManager.clear()
}